<template>
  <div>
    <VueUeditorWrap
      v-model="ueditorValue"
      :config="ueditorConfig"
      :editor-id="editorId"
      @before-init="ueditorInit"
      :key="editorId"
    />

    <!-- 素材库 -->
    <WarehouseModal ref="WarehouseModal" :limit="0" :fileSource="fileSource" @select="handSelect" />
    <UploadFile
      v-show="false"
      ref="UploadFile"
      @uploadSuccess="handleUploadSuccess"
      :maxNum="1"
      :openMessage="false"
      @change="handleChange"
    ></UploadFile>
  </div>
</template>

<script>
import VueUeditorWrap from 'vue-ueditor-wrap'
import WarehouseModal from '@/components/UpFile/warehouseModal'
import { checkPermission } from '@/utils/authority'
import UploadFile from '@/components/UploadFile/index.vue'
import { buildUUID } from '@/utils/uuid'

const toolbars = [
  [
    'source', //代码语言
    '|',
    'anchor', //锚点
    'undo', //撤销
    'redo', //重做
    'bold', //加粗
    'indent', //首行缩进
    'italic', //斜体
    'underline', //下划线
    'strikethrough', //删除线
    'subscript', //下标
    'fontborder', //字符边框
    'superscript', //上标
    'formatmatch', //格式刷
    'blockquote', //引用
    'pasteplain', //纯文本粘贴模式
    'selectall', //全选
    'print', //打印
    'preview', //预览
    'horizontal', //分隔线
    'removeformat', //清除格式
    'time', //时间
    'date', //日期
    // 'insertrow', //前插入行
    // 'insertcol', //前插入列
    // 'mergeright', //右合并单元格
    // 'mergedown', //下合并单元格
    // 'deleterow', //删除行
    // 'deletecol', //删除列
    // 'splittorows', //拆分成行
    // 'splittocols', //拆分成列
    // 'splittocells', //完全拆分单元格
    // 'deletecaption', //删除表格标题
    // 'inserttitle', //插入标题
    // 'mergecells', //合并多个单元格
    // 'deletetable', //删除表格
    'cleardoc', //清空文档
    // 'insertparagraphbeforetable', //"表格前插入行"
    'fontfamily', //字体
    'fontsize', //字号
    'paragraph', //段落格式
    // 'edittable', //表格属性
    'edittd', //单元格属性
    'spechars', //特殊字符
    'searchreplace', //查询替换
    'justifyleft', //居左对齐
    'justifyright', //居右对齐
    'justifycenter', //居中对齐
    'justifyjustify', //两端对齐
    'forecolor', //字体颜色
    'backcolor', //背景色
    'insertorderedlist', //有序列表
    'insertunorderedlist', //无序列表
    'fullscreen', //全屏
    'directionalityltr', //从左向右输入
    'directionalityrtl', //从右向左输入
    'rowspacingtop', //段前距
    'rowspacingbottom', //段后距
    'pagebreak', //分页
    'imagenone', //默认
    'lineheight', //行间距
    'edittip ', //编辑提示
    'customstyle', //自定义标题
    'autotypeset', //自动排版
    'touppercase', //字母大写
    'tolowercase', //字母小写
    // 'inserttable', //插入表格
    '|',
    'imageleft', //左浮动
    'imageright', //右浮动
    'imagecenter', //居中
    'simpleupload',
    'warehouseimage',
    'warehousevideo',
    'attachment' //附件
  ]
]

export default {
  props: {
    value: {
      type: String,
      required: true,
      default: ''
    },
    // 富文本唯一ID, 全局不可重复, 避免存在多个富文本页面存在切换,渲染问题
    editorId: {
      type: String,
      required: true,
      default: 'ud' + buildUUID()
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    value: {
      handler(val) {
        this.ueditorValue = val
      },
      deep: true,
      immediate: true
    },
    ueditorValue(nval) {
      this.$emit('input', nval)
    },
    disabled: {
      handler(val) {
        this.ueditorConfig.toolbars = val ? [] : toolbars
      },
      immediate: true
    }
  },
  components: {
    VueUeditorWrap,
    WarehouseModal,
    UploadFile
  },
  data() {
    return {
      fileSource: 'image',

      ueditor: {}, // 富文本实例
      ueditorValue: '',
      ueditorConfig: {
        // 编辑器不自动被内容撑高
        autoHeightEnabled: false,
        // 初始容器高度
        initialFrameHeight: 400,
        // 初始容器宽度
        initialFrameWidth: '100%',
        UEDITOR_HOME_URL: '/static/UEditor/',
        serverUrl: process.env.VUE_APP_API_BASE_URL + '/system/ueditor/opt',
        toolbars: toolbars,
        autoFloatEnabled: false
      }
    }
  },
  methods: {
    // https://juejin.cn/post/7041764200439840804
    ueditorInit() {
      this.ueditor = UE
      if (checkPermission('content:warehouse:list')) {
        this.initUeditor('image')
        this.initUeditor('video')
        this.initAchment()
      }
    },
    handleChange(info) {
      const ueditor = this.ueditor
      const ue = ueditor.getEditor(this.editorId)
      const aTag = ue.iframe.contentWindow.document.getElementById(info.file.uid)

      if (aTag) {
        const pTag = aTag.parentNode
        aTag.parentNode.removeChild(aTag)

        let desc = `---上传中${info.file.percent.toFixed(2)}%`
        if (info.file.status === 'error') desc = `---上传失败`
        if (info.file.percent == 100) desc = '---上传即将完成'
        const attachment = `<a id="${info.file.uid}" style="font-size: 16px;" href="${info.file.url}" download="true">📁${info.file.name}${desc}</a>`
        pTag.innerHTML = attachment
      } else {
        const attachment = `<p><a id="${info.file.uid}" style="font-size: 16px;" href="${info.file.url}" download="true">📁${info.file.name}</a></p>`
        ue.execCommand('insertHtml', attachment)
      }
    },
    handleUploadSuccess(fileUrl, { name, uid }) {
      const ueditor = this.ueditor
      const ue = ueditor.getEditor(this.editorId)
      const aTag = ue.iframe.contentWindow.document.getElementById(uid)
      if (aTag) {
        const attachment = `<a id="${uid}" style="font-size: 16px;" href="${fileUrl}" download="true">📁${name}</a>`
        const pTag = aTag.parentNode
        aTag.parentNode.removeChild(aTag)
        pTag.innerHTML = attachment
        ue.focus()
        this.$message.success(`${name} 上传成功`)
      }
    },
    initAchment() {
      const that = this
      const index = 72
      const name = 'attachment'
      const ueditor = that.ueditor
      ueditor.registerUI(
        name, // 按钮名称
        function(editor, uiName) {
          const cssRules = 'background-position: -650px -78px;'
          //创建一个button
          var btn = new UE.ui.Button({
            //按钮的名字
            name: uiName,
            //提示
            title: '添加附件',
            //添加额外样式,指定icon图标,这里默认使用一个重复的icon
            cssRules,
            //点击时执行的命令
            onclick: function() {
              that.fileSource = 'attachment'
              that.$refs.UploadFile.$el.firstChild.firstChild.click()
            }
          })

          //当点到编辑内容上时，按钮要做的状态反射
          editor.addListener('selectionchange', function() {
            var state = editor.queryCommandState(uiName)
            btn.setDisabled(state == -1 ? true : false)
            btn.setChecked(state == -1 ? false : state)
          })
          //因为你是添加button,所以需要返回这个button
          return btn
        },
        index, // 放置在toolbar的位置
        [that.editorId]
      )
    },
    // 添加自定义按钮
    initUeditor(iconType) {
      const that = this
      const ueditor = that.ueditor
      const name = `warehouse${iconType}`
      const title = iconType === 'video' ? '从素材库选择视频' : '从素材库选择图片'
      const cssRules =
        iconType === 'video' ? 'background-position: -321px -20px;' : 'background-position: -726px -78px;'
      const index = iconType === 'video' ? 71 : 70

      ueditor.registerUI(
        name, // 按钮名称
        function(editor, uiName) {
          //创建一个button
          var btn = new UE.ui.Button({
            //按钮的名字
            name: uiName,
            //提示
            title,
            //添加额外样式,指定icon图标,这里默认使用一个重复的icon
            cssRules,
            //点击时执行的命令
            onclick: function() {
              that.fileSource = iconType
              that.$refs.WarehouseModal.show()
            }
          })

          //当点到编辑内容上时，按钮要做的状态反射
          editor.addListener('selectionchange', function() {
            var state = editor.queryCommandState(uiName)
            btn.setDisabled(state == -1 ? true : false)
            btn.setChecked(state == -1 ? false : state)
          })
          //因为你是添加button,所以需要返回这个button
          return btn
        },
        index, // 放置在toolbar的位置
        [that.editorId]
      )
    },
    // 素材库选择图片后
    handSelect(items) {
      const that = this
      const ueditor = that.ueditor
      const ue = ueditor.getEditor(that.editorId)
      if (that.fileSource === 'video') {
        // 视频
        let videos = ''
        items.forEach(v => {
          videos += `<p><br/><video src="${v}" style="width:200px;" controls><span style="display:none;">.</span></video></p>`
        })
        ue.execCommand('insertHtml', videos)
        ue.focus()
      } else {
        // 图片
        let urlList = items.map(v => {
          return {
            src: v
          }
        })
        urlList && urlList.length && ue.execCommand('insertimage', urlList)
        ue.focus()
      }
    }
  }
}
</script>

<style lang="less">
textarea[name='editorValue'] {
  opacity: 0;
}
</style>
